﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Web.UI;
using System.Web.UI.WebControls;
using pos12.Models;
using DevExpress.Web.ASPxEditors;

namespace pos12.Pages
{
    public static class Extensions
    {
        public static IEnumerable<Control> FindAll(this ControlCollection collection)
        {
            foreach (Control item in collection)
            {
                yield return item;

                if (item.HasControls())
                {
                    foreach (var subItem in item.Controls.FindAll())
                    {
                        yield return subItem;
                    }
                }
            }
        }


        public static void BindArrayToEnum(this List<ASPxComboBox> controls, Array array)
        {
            foreach (var control in controls)
            {
                control.DataSource = array;
                control.DataBind();
                control.SelectedIndex = 0;
            }
        }
    }
    public partial class Posuvniky : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            PosyvnikyAdminModel model = GetDataFromDB();
            //bool isAdmin = IsUserAdmin();
            SetFieldsValues(model, false);
            SetEditableToFields(false);

            SetPosuvnikyLabelValuesAndStyles(model);
        }

        private void SetPosuvnikyLabelValuesAndStyles(PosyvnikyAdminModel model)
        {
            SetPosuvnikyLabelFirstBlockValues(model);
            SetPosuvnikyLabelFirstBlockStyles();
            SetPosuvnikyLabelSecondBlockValues(model);
        }

        private void SetPosuvnikyLabelFirstBlockStyles()
        {
            List<Control> allControls = Controls.FindAll().ToList();

            List<ASPxDateEdit> adminControlsDate = (from contr in allControls
                                                    let currType = contr.GetType()
                                                    where currType == typeof(ASPxDateEdit)
                                                     && contr.Parent == PlaceHolderPosuvmikyFirstBlock
                                                    select contr)
                                                      .Cast<ASPxDateEdit>().ToList();

            foreach (var asPxDateEdit in adminControlsDate)
            {
                asPxDateEdit.Font.Bold = true;
                asPxDateEdit.ForeColor = Color.RoyalBlue;
                asPxDateEdit.DropDownButton.Visible = true;
                asPxDateEdit.Width = asPxDateEdit.Text.Length * 10 ;
            }
        }

        private void SetPosuvnikyLabelFirstBlockValues(PosyvnikyAdminModel model)
        {
            freeDays.Text = model.FreeDays.ToString(CultureInfo.InvariantCulture);
            datefrom.Value = model.DateFrom;

            var dateToS = model.DateFrom.AddDays((int)(model.MinPriceWithoutDiscount / model.OneDayPlacementPrice));
            dateto.Value = dateToS;

            var daysRangeS = (dateToS - model.DateFrom).Days;
            daysRange.Text = daysRangeS.ToString(CultureInfo.InvariantCulture);

            var discountTermS = (model.MaxDiscountTerm - 0)*daysRangeS/model.MaxDays;
            discountTerm.Text = discountTermS.ToString(CultureInfo.InvariantCulture);

            var priceBeforeDiscountS = daysRangeS*model.OneDayPlacementPrice;
            priceBeforeDiscount.Text = priceBeforeDiscountS.ToString(CultureInfo.InvariantCulture);

            var priceAfterDiscountS = priceBeforeDiscountS*(100 - discountTermS) / 100;
            priceAfterDiscount.Text = priceAfterDiscountS.ToString(CultureInfo.InvariantCulture);

        }

        private void SetPosuvnikyLabelSecondBlockValues(PosyvnikyAdminModel model)
        {
            //todo: 
            var daysRangeS = Int32.Parse(daysRange.Text);
            var minLifts = 100;
            var maxLifts = daysRangeS;

            var liftmessagefrequncyS = minLifts;
            liftmessagefrequncy.Text = liftmessagefrequncyS.ToString(CultureInfo.InvariantCulture);

            //todo:
            liftmessagetime.Text = 5.ToString(CultureInfo.InvariantCulture);

            var liftmessagecountS = Math.Min(minLifts, (int) (model.MinPriceForRaiseWithoutDiscount/model.OneLiftPrice));
            liftmessagecount.Text = liftmessagecountS.ToString(CultureInfo.InvariantCulture);

            var discountTermS = (model.MaxDiscountTopper - 0) * liftmessagecountS / maxLifts;
            discountLifts.Text = discountTermS.ToString(CultureInfo.InvariantCulture);
        }

        private void SetEditableToFields(bool isEditable)
        {
            SetEditabilityToTxtBoxes(isEditable);
            SetVisiblityToSubmitButtons(isEditable);
            SetVisiblityToEditButtons(IsUserAdmin());
            SetVisiblityToCancelButtons(isEditable);
        }

        private void SetVisiblityToCancelButtons(bool isVisible)
        {
            btnCancelPosuvniky1.Visible = isVisible;
            btnCancelPosuvniky2.Visible = isVisible;
            btnCancelPosuvniky3.Visible = isVisible;
        }

        private void SetVisiblityToEditButtons(bool isVisible)
        {
            btnEditPosuvniky1.Visible = isVisible;
            btnEditPosuvniky2.Visible = isVisible;
            btnEditPosuvniky3.Visible = isVisible;
        }

        private void SetFieldsValues(PosyvnikyAdminModel model, bool isEditable)
        {
            dateFormate.Value = model.dateFormate;SetValuesToDropDownLists(isEditable);
            SetValuesToFirstBlockFields(model);
            SetValuesToSecondBlockFields(model);
            SetValuesToThirdBlockFields(model);
        }

        private void SetValuesToThirdBlockFields(PosyvnikyAdminModel model)
        {
            ASPxMinRewardAgent.Text = model.MinRewardAgent.ToString(CultureInfo.InvariantCulture);
            ASPxMaxRewardAgent.Text = model.MaxRewardAgent.ToString(CultureInfo.InvariantCulture);
        }

        private void SetValuesToSecondBlockFields(PosyvnikyAdminModel model)
        {
                ASPxMinRaiseCount.Text = model.MinLifts.ToString(CultureInfo.InvariantCulture);
                ASPxMaxRaiseCount.Text = model.MaxLifts.ToString(CultureInfo.InvariantCulture);
                ASPxMinPriceForRaise.Text = model.MinPriceForRaise.ToString(CultureInfo.InvariantCulture);
                ASPxMaxPriceForRaise.Text = model.MaxPriceForRaise.ToString(CultureInfo.InvariantCulture);
                ASPxMaxDiscountTopper.Text = model.MaxDiscountTopper.ToString(CultureInfo.InvariantCulture);
                ASPxMinPriceForRaiseWithout.Text = model.MinPriceForRaiseWithoutDiscount.ToString(CultureInfo.InvariantCulture);
                ASPxOneLiftPrice.Text = model.OneLiftPrice.ToString(CultureInfo.InvariantCulture);
        }

        private void SetValuesToFirstBlockFields(PosyvnikyAdminModel model)
        {
            ASPxDatefrom.EditFormatString = model.dateFormate;
            ASPxDateTo.EditFormatString = model.dateFormate;
            ASPxDatefrom.DisplayFormatString = model.dateFormate;
            ASPxDateTo.DisplayFormatString = model.dateFormate;
            ASPxFreeDays.Text = model.FreeDays.ToString(CultureInfo.InvariantCulture);
            ASPxMaxDays.Text = model.MaxDays.ToString(CultureInfo.InvariantCulture);
            ASPxDatefrom.Value = model.DateFrom;
            ASPxDateTo.Value = model.DateTo;
            ASPxMinPriceWithDiscount.Text = model.MinPriceWithDiscount.ToString(CultureInfo.InvariantCulture);
            ASPxMaxDiscount.Text = model.MaxDiscountTerm.ToString(CultureInfo.InvariantCulture);
            ASPxMinPriceWithoutDiscount.Text = model.MinPriceWithoutDiscount.ToString(CultureInfo.InvariantCulture);
            ASPxOneDayPlacementPrice.Text = model.OneDayPlacementPrice.ToString(CultureInfo.InvariantCulture);
            datefrom.DisplayFormatString = model.dateFormate;
            dateto.DisplayFormatString = model.dateFormate;
            datefrom.EditFormatString = model.dateFormate;
            dateto.EditFormatString = model.dateFormate;
            datefrom.MinDate = model.DateFrom.AddDays(-1);
            dateto.MaxDate = model.DateTo.AddDays(-1);

        }

        private void SetVisiblityToSubmitButtons(bool isAdmin)
        {
            btnSbmtPosuvniky1.Visible = isAdmin;
            btnSbmtPosuvniky2.Visible = isAdmin;
            btnSbmtPosuvniky3.Visible = isAdmin;
        }

        private void SetEditabilityToTxtBoxes(bool isEditable)
        {
            SetEditableControls(isEditable, PlaceHolderFirstBlock);
            SetEditableControls(isEditable, PlaceHolderSecondBlock);
            SetEditableControls(isEditable, PlaceHolderThirdBlock);
            
        }

        private void SetValuesToDropDownLists(bool isEditable)
        {
            if (!isEditable)
            {
                var currencyEnumArray = Enum.GetValues(typeof (CurrencyEnum));
                var dropDownList = new List<ASPxComboBox>
                {
                    ddlCurrencyMinPrice,
                    ddlCurrencyMinPriceWithoutDiscount,
                    ddlCurrencyMinPriceForRaise,
                    ddlCurrencyMaxPriceForRaise,
                    ddlCurrencyMinPriceForRaiseWithout,
                    ddlOneLiftPrice,
                    ddlCurrencyOneDayPlacementPrice
                };
                dropDownList.BindArrayToEnum(currencyEnumArray);
            }
        }

        private bool IsUserAdmin()
        {
            return true;
        }

        private PosyvnikyAdminModel GetDataFromDB()
        {
            var model = new PosyvnikyAdminModel
                        {
                            FreeDays = 30,
                            DateFrom = DateTime.Now,
                            DateTo = DateTime.Now.AddYears(1),
                            MaxDays = Convert.ToInt32(396),
                            MinPriceWithDiscount = 200,
                            MaxDiscountTerm = 90,
                            MinPriceWithoutDiscount = 250,
                            OneDayPlacementPrice = 2,

                            MinLifts = 1,
                            MaxLifts = 365,
                            MinPriceForRaise = 10,
                            MaxPriceForRaise = 1000,
                            MaxDiscountTopper = 60,
                            MinPriceForRaiseWithoutDiscount = 17,
                            OneLiftPrice = 12,

                            //LiftsCountPerDays = 1,
                            //LiftsCountDays = 1,
                            MinRewardAgent = 10,
                            MaxRewardAgent = 90
                        };
            //model.MinPriceWithoutDiscount = (model.MinPriceWithDiscount + (float)model.MaxDiscountTerm / 100) *
            //                                model.MinPriceWithDiscount;
            return model;
        }

        private void SetEditableControls(bool isEditable, Control parentControl)
        {
            btnCancelPosuvniky1.ImageUrl = @"~/Content/themes/pSliders/Images/cancel.jpg";
            btnCancelPosuvniky2.ImageUrl = @"~/Content/themes/pSliders/Images/cancel.jpg";
            btnCancelPosuvniky3.ImageUrl = @"~/Content/themes/pSliders/Images/cancel.jpg";
            btnSbmtPosuvniky1.ImageUrl = @"~/Content/themes/pSliders/Images/Save1.png";
            btnSbmtPosuvniky2.ImageUrl = @"~/Content/themes/pSliders/Images/Save.png";
            btnSbmtPosuvniky3.ImageUrl = @"~/Content/themes/pSliders/Images/Save.png";
            btnEditPosuvniky1.ImageUrl = @"~/Content/themes/pSliders/Images/editPencil.gif";
            btnEditPosuvniky2.ImageUrl = @"~/Content/themes/pSliders/Images/editPencil.gif";
            btnEditPosuvniky3.ImageUrl = @"~/Content/themes/pSliders/Images/editPencil.gif";

            List<Control> allControls = Controls.FindAll().ToList();

            List<ASPxSpinEdit> adminControlsSnippers = (from contr in allControls let currType = contr.GetType() 
                                                        where currType == typeof(ASPxSpinEdit)
                                                        && contr.Parent == parentControl
                                                        select contr)
                                                        .Cast<ASPxSpinEdit>().ToList();

            List<ASPxComboBox> adminControlsCombos = (from contr in allControls let currType = contr.GetType() 
                                                      where currType == typeof(ASPxComboBox)
                                                       && contr.Parent == parentControl
                                                      select contr)
                                                      .Cast<ASPxComboBox>().ToList();

            List<ASPxDateEdit> adminControlsDate = (from contr in allControls
                                                    let currType = contr.GetType()
                                                    where currType == typeof(ASPxDateEdit)
                                                     && contr.Parent == parentControl
                                                    select contr)
                                                      .Cast<ASPxDateEdit>().ToList();
            if (!isEditable)
            {
                AddCssClass(adminControlsCombos,"hideBorder");
                AddCssClass(adminControlsSnippers, "hideBorder");
                AddCssClass(adminControlsDate, "hideBorder"); 
            }
            else
            {
                RemoveCssClass(adminControlsCombos, "hideBorder");
                RemoveCssClass(adminControlsSnippers, "hideBorder");
                RemoveCssClass(adminControlsDate, "hideBorder");
            }
            
            foreach (var adminControlsCombo in adminControlsCombos)
            {
                //adminControlsCombo.ForeColor = Color.RoyalBlue;
                adminControlsCombo.Font.Bold = true;
                adminControlsCombo.DropDownButton.Visible = isEditable;
                adminControlsCombo.ReadOnly = !isEditable;
                adminControlsCombo.Width = !isEditable ? adminControlsCombo.SelectedItem.Text.Length * 13 : 50;
                
            }
            foreach (var adminControlsSnipper in adminControlsSnippers)
            {
                adminControlsSnipper.ForeColor = Color.DarkRed;
                adminControlsSnipper.Font.Bold = true;
                adminControlsSnipper.SpinButtons.ShowIncrementButtons = isEditable;
                adminControlsSnipper.ReadOnly = !isEditable;
                adminControlsSnipper.Width = !isEditable ? adminControlsSnipper.Text.Length * 13 : 58;
            }
            foreach (var asPxDateEdit in adminControlsDate)
            {
                asPxDateEdit.Font.Bold = true;
                asPxDateEdit.ForeColor = Color.RoyalBlue;
                asPxDateEdit.DropDownButton.Visible = isEditable;
                asPxDateEdit.Width = asPxDateEdit.Text.Length * 10;
            }
        }

        protected void btnEditPosuvniky1_Click(object sender, EventArgs e)
        {
            btnSbmtPosuvniky1.Visible = true;
            btnEditPosuvniky1.Visible = false;
            btnCancelPosuvniky1.Visible = true;
            PosyvnikyAdminModel model = GetDataFromDB();
            SetValuesToFirstBlockFields(model);
            SetValuesToDropDownLists(true);
            SetEditableControls(true, PlaceHolderFirstBlock);
        }

        protected void btnEditPosuvniky2_Click(object sender, EventArgs e)
        {
            btnSbmtPosuvniky2.Visible = true;
            btnEditPosuvniky2.Visible = false;
            btnCancelPosuvniky2.Visible = true;
            SetEditableControls(true, PlaceHolderSecondBlock);
            PosyvnikyAdminModel model = GetDataFromDB();
            SetValuesToSecondBlockFields(model);
            SetValuesToDropDownLists(true);
        }

        protected void btnEditPosuvniky3_Click(object sender, EventArgs e)
        {
            btnSbmtPosuvniky3.Visible = true;
            btnEditPosuvniky3.Visible = false;
            btnCancelPosuvniky3.Visible = true;
            SetEditableControls(true, PlaceHolderThirdBlock);
            PosyvnikyAdminModel model = GetDataFromDB();
            SetValuesToThirdBlockFields(model);
            SetValuesToDropDownLists(true);
        }

        protected void btnCancelPosuvniky1_Click(object sender, EventArgs e)
        {
            btnSbmtPosuvniky1.Visible = false;
            btnEditPosuvniky1.Visible = true;
            btnCancelPosuvniky1.Visible = false;
            SetEditableControls(false, PlaceHolderFirstBlock);
            PosyvnikyAdminModel model = GetDataFromDB();
            SetValuesToFirstBlockFields(model);
            SetValuesToDropDownLists(false);
        }

        protected void btnCancelPosuvniky2_Click(object sender, EventArgs e)
        {
            btnSbmtPosuvniky2.Visible = false;
            btnEditPosuvniky2.Visible = true;
            btnCancelPosuvniky2.Visible = false;
            SetEditableControls(false, PlaceHolderSecondBlock);
            PosyvnikyAdminModel model = GetDataFromDB();
            SetValuesToSecondBlockFields(model);
            SetValuesToDropDownLists(false);
        }

        protected void btnCancelPosuvniky3_Click(object sender, EventArgs e)
        {
            btnSbmtPosuvniky3.Visible = false;
            btnEditPosuvniky3.Visible = true;
            btnCancelPosuvniky3.Visible = false;
            SetEditableControls(false, PlaceHolderThirdBlock);
            PosyvnikyAdminModel model = GetDataFromDB();
            SetValuesToThirdBlockFields(model);
            SetValuesToDropDownLists(false);
        }


        protected void btnSbmtPosuvniky1_Click(object sender, EventArgs e)
        {
            btnSbmtPosuvniky1.Visible = false;
            btnEditPosuvniky1.Visible = true;
            btnCancelPosuvniky1.Visible = false;
            SetEditableControls(false, PlaceHolderFirstBlock);
            SetValuesToDropDownLists(false);
            PosyvnikyAdminModel model = GetDataFromDB();
            SetValuesToFirstBlockFields(model);
            //var model = new PosyvnikyAdminModel
            //{
            //    //Currency = 
            //    FreeDays = Convert.ToInt16(ASPxFreeDays.Text),
            //    MaxDays = Convert.ToInt16(ASPxMaxDays.Text),
            //    MinPriceWithDiscount = Convert.ToInt32(ASPxMinPriceWithDiscount.Text),
            //    MaxDiscountTerm = Convert.ToInt16(ASPxMaxDiscount.Text),
            //    MinPriceWithoutDiscount = Convert.ToInt32(ASPxMinPriceWithoutDiscount.Text),
            //};

        }

        protected void btnSbmtPosuvniky2_Click(object sender, EventArgs e)
        {
            btnSbmtPosuvniky2.Visible = false;
            btnEditPosuvniky2.Visible = true;
            btnCancelPosuvniky2.Visible = false;
            SetEditableControls(false, PlaceHolderSecondBlock);
            SetValuesToDropDownLists(false);
            PosyvnikyAdminModel model = GetDataFromDB();
            SetValuesToSecondBlockFields(model);
            //var model = new PosyvnikyAdminModel
            //{
            //    //Currency = 
            //    FreeDays = Convert.ToInt16(ASPxFreeDays.Text),
            //    MaxDays = Convert.ToInt16(ASPxMaxDays.Text),
            //    MinPriceWithDiscount = Convert.ToInt32(ASPxMinPriceWithDiscount.Text),
            //    MaxDiscountTerm = Convert.ToInt16(ASPxMaxDiscount.Text),
            //    MinPriceWithoutDiscount = Convert.ToInt32(ASPxMinPriceWithoutDiscount.Text),
            //};

        }

        protected void btnSbmtPosuvniky3_Click(object sender, EventArgs e)
        {
            btnSbmtPosuvniky3.Visible = false;
            btnEditPosuvniky3.Visible = true;
            btnCancelPosuvniky3.Visible = false;
            SetEditableControls(false, PlaceHolderThirdBlock);
            SetValuesToDropDownLists(false);
            PosyvnikyAdminModel model = GetDataFromDB();
            SetValuesToThirdBlockFields(model);
            //var model = new PosyvnikyAdminModel
            //{
            //    //Currency = 
            //    FreeDays = Convert.ToInt16(ASPxFreeDays.Text),
            //    MaxDays = Convert.ToInt16(ASPxMaxDays.Text),
            //    MinPriceWithDiscount = Convert.ToInt32(ASPxMinPriceWithDiscount.Text),
            //    MaxDiscountTerm = Convert.ToInt16(ASPxMaxDiscount.Text),
            //    MinPriceWithoutDiscount = Convert.ToInt32(ASPxMinPriceWithoutDiscount.Text),
            //};

        }

        private void AddCssClass<T>(IEnumerable<T> controlArr, string cssClass)
        {
            foreach (var controlC in controlArr)
            {
                var control = controlC as WebControl;

                if (string.IsNullOrEmpty(control.CssClass))
                {
                    control.CssClass = cssClass;
                }
                else
                {
                    string[] cssClasses = control. CssClass.Split(' ');
                    bool classExists = cssClasses.Any(@class => @class == cssClass);

                    if (!classExists)
                    {
                        control.CssClass += " " + cssClass;
                    }
                }
            }
            
        }

        private void RemoveCssClass<T>(IEnumerable<T> controlArr, string cssClass)
        {
            foreach (var controlC in controlArr)
            {
                var control = controlC as WebControl;
                if (!string.IsNullOrEmpty(control.CssClass))
                {
                    string[] cssClasses = control.CssClass.Split(' ');
                    control.CssClass = string.Join(" ", cssClasses.Where(@class => @class != cssClass).ToArray());
                }
            }
        }
    }
}